#pragma once

#include <QObject>
#include <QMetaType>
#include <QMetaEnum>
#include <QFileInfo>
#include <QDebug>

// Debug functions caller stack tracker
#ifndef FUNCTION_TRACE
#  if defined (DEBUG_FTRACE)
#    if defined (DEBUG_FTRACE_FILE_FUNC)
#      define FUNCTION_TRACE    qDebug().noquote() << QString::asprintf("[%s:%d]<%s>", __FILE__, __LINE__, __FUNCTION__)
#    else
#      define FUNCTION_TRACE    qDebug().noquote() << QString::asprintf("<%s>", __FUNCTION__)
#    endif
#  else
#    define FUNCTION_TRACE      QT_NO_QDEBUG_MACRO()
#  endif
#endif

// Object safe deleter
#ifndef SAFE_DELETE
#define SAFE_DELETE(x)          if (x) { delete x; x = nullptr; }
#endif
#ifndef SAFE_DELETE_LATER
#define SAFE_DELETE_LATER(x)    if (x) { x->deleteLater(); x = nullptr; }
#endif

// Unit Convert
#ifndef UNIT_CONVERT
#define UNIT_CONVERT
#define UNIT_KB             (1024)
#define UNIT_MB             (UNIT_KB * 1024)
#define UNIT_GB             (UNIT_MB * 1024)
#define UNIT_TB             (UNIT_GB * 1024)
#define UNIT_TO_KB(x)       (x / UNIT_KB)
#define UNIT_TO_MB(x)       (x / UNIT_MB)
#define UNIT_TO_GB(x)       (x / UNIT_GB)
#define UNIT_TO_TB(x)       (x / UNIT_TB)
#endif

// Qt custom meta type register
#ifndef RegisterMetaTypes
#define RegisterMetaTypes(X) { \
    qRegisterMetaType<X>(#X); \
    qRegisterMetaType<X>(#X"&"); \
    qRegisterMetaType< QVector<X> >("QVector<"#X">"); \
    qRegisterMetaType< QVector<X> >("QVector<"#X">&"); \
}
#endif

#ifndef RegisterMetaTypeStreamOperators
#define RegisterMetaTypeStreamOperators(X) { \
    qRegisterMetaTypeStreamOperators<X>(#X); \
    qRegisterMetaTypeStreamOperators<X>(#X"&"); \
    qRegisterMetaTypeStreamOperators< QVector<X> >("QVector<"#X">"); \
    qRegisterMetaTypeStreamOperators< QVector<X> >("QVector<"#X">&"); \
}
#endif
